package com.abel.web.controller;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;

import com.abel.domain.AccountInfo;
import com.abel.domain.AuthPrincipal;
import com.abel.domain.AuthRequest;
import com.abel.domain.types.PersonType;
import com.abel.manager.AuthenticationManager;
import com.abel.manager.RegistrationManager;
import com.abel.manager.exception.AuthenticationException;
import com.abel.manager.exception.RegistrationException;
import com.abel.repository.exception.DuplicateUserException;
import com.abel.web.view.RegistrationViewBean;

public class RegistrationController extends SimpleFormController {

	protected final Log logger = LogFactory.getLog(getClass());
	
	//injected using spring
	private RegistrationManager registrationManager;

	private AuthenticationManager authenticationManager;
	
	/**
	 * @param authenticationManager the authenticationManager to set
	 */
	public void setAuthenticationManager(AuthenticationManager authenticationManager) {
		this.authenticationManager = authenticationManager;
	}



	public ModelAndView onSubmit( HttpServletRequest request,
								HttpServletResponse response, 
								Object command, 
								BindException errors) throws Exception {

		
		logger.debug("@RegistrationController : onSubmit : entered");
		
		RegistrationViewBean bean = (RegistrationViewBean)command;
	
		//convert to domain
		AccountInfo accountInfo = new AccountInfo();
		accountInfo.setUserName(bean.getUserName());
		accountInfo.setPassword(bean.getPassword());
		accountInfo.setEmail(bean.getEmail());
		accountInfo.setPersonType(bean.getRole() == null || 
				bean.getRole().equals("") ? 
						PersonType.User : 
							PersonType.valueOf(bean.getRole()));
		
		//register user
		int userId = -1;
		try {
			
			userId = this.registrationManager.registerApplicant(accountInfo);
		
		} 
		catch (RegistrationException e) {
			
			logger.error("@RegistrationController : onSubmit : Exception while registering" + e);
			e.printStackTrace();
			request.setAttribute("registrationView", bean);
			errors.rejectValue("", "error.null",null,"We were not able to register you at this point of time.  Please resubmit the application");
			return showForm(request,response,errors);
			
		}
		catch (DuplicateUserException e) {
			
			logger.error("@RegistrationController : onSubmit : Duplicate user exception " + e);
			errors.rejectValue("", "error.null",null,"The user id you choose already exists.  Please resubmit the application with a different user id");
			return showForm(request,response,errors);
		}
		
		
		//if registered successful, authenticate and authorize user
		if (userId != -1) {
			AuthRequest authRequest = new AuthRequest();
			authRequest.setUserName(accountInfo.getUserName());
			authRequest.setPassword(accountInfo.getPassword());
			try {

				@SuppressWarnings("unused")
				AuthPrincipal authPrincipal = authenticationManager.getAuthPrincipal(authRequest);
			} 
			catch (AuthenticationException e) {

				logger.error("@RegistrationController : onSubmit : Exception while authenticating after registering user " + e);
				errors.rejectValue("", "error.null",null,"We were not able to register you at this point of time.  Please resubmit the application");
				e.printStackTrace();
				return showForm(request,response,errors);
			}
		}
		return new ModelAndView("redirect:" + getSuccessView());
	}
	
	
	private ModelAndView regularUserLogin(AccountInfo accountInfo, 
			BindException errors) {
		
		logger.debug("@RegistrationController : onSubmit : entered");

		return null;
	}

	
	private ModelAndView adminLogin(AccountInfo accountInfo, 
			BindException errors) {

		logger.debug("@RegistrationController : onSubmit : entered");

		return null;
	}
	
	private ModelAndView login(AccountInfo accountInfo , 
			BindException errors) {

		logger.debug("@RegistrationController : onSubmit : entered");

		return null;
	}
	
	
	protected Object formBackingObject(HttpServletRequest request)
    	throws ServletException {
		
		RegistrationViewBean registerView = new RegistrationViewBean();
		//if the request type is adminregister then set it as super user
		if (request.getRequestURI().indexOf("/adminregister.xhtm") != -1) {
			
			registerView.setAdminRequest(true);
		
		}
		return registerView;
	}
	
	
	public void setRegistrationManager(RegistrationManager registrationManager) {
		this.registrationManager = registrationManager;
	}

	

}
